/**
 * JSON Configuration Manager
 * Provides configuration management using JSON files instead of .env files
 */

const fs = require('fs');
const path = require('path');
const { validateConfig } = require('./validator');

class JsonConfigManager {
    constructor(projectRoot) {
        this.projectRoot = projectRoot;

        // 使用跨平台标准路径
        const ConfigPathResolver = require('./config-path-resolver');
        const pathResolver = new ConfigPathResolver();

        this.configPath = pathResolver.getConfigFilePath();
        this.config = null;
        this.lastModified = null;
    }

    /**
     * Load configuration from JSON file
     * @returns {Object} Configuration object
     */
    loadConfig() {
        try {
            if (!fs.existsSync(this.configPath)) {
                throw new Error(`Configuration file not found: ${this.configPath}`);
            }

            const stats = fs.statSync(this.configPath);

            // Check if file has been modified since last load
            if (this.config && this.lastModified && stats.mtime <= this.lastModified) {
                return this.config;
            }

            const configContent = fs.readFileSync(this.configPath, 'utf8');
            this.config = JSON.parse(configContent);
            this.lastModified = stats.mtime;

            // Validate configuration
            const validation = validateConfig(this.config);
            if (!validation.success) {
                console.warn('Configuration validation warnings:', validation.errors);
            }

            return this.config;
        } catch (error) {
            console.error('Failed to load configuration:', error.message);
            throw error;
        }
    }

    /**
     * Get current configuration (alias for loadConfig for compatibility)
     * @returns {Object} Configuration object
     */
    getConfig() {
        return this.config || this.loadConfig();
    }

    /**
     * Get configuration value by path (e.g., 'providers.tencent.api_key')
     * @param {string} configPath - Dot notation path to config value
     * @param {*} defaultValue - Default value if path not found
     * @returns {*} Configuration value
     */
    get(configPath, defaultValue = null) {
        const config = this.loadConfig();
        const keys = configPath.split('.');
        let current = config;

        for (const key of keys) {
            if (current && typeof current === 'object' && key in current) {
                current = current[key];
            } else {
                return defaultValue;
            }
        }

        return current;
    }

    /**
     * Set configuration value by path
     * @param {string} configPath - Dot notation path to config value
     * @param {*} value - Value to set
     */
    set(configPath, value) {
        const config = this.loadConfig();
        const keys = configPath.split('.');
        let current = config;

        for (let i = 0; i < keys.length - 1; i++) {
            const key = keys[i];
            if (!(key in current) || typeof current[key] !== 'object') {
                current[key] = {};
            }
            current = current[key];
        }

        current[keys[keys.length - 1]] = value;
        this.saveConfig(config);
    }

    /**
     * Save configuration to JSON file
     * @param {Object} config - Configuration object to save
     * @param {boolean} testMode - Whether to enable test mode validation
     */
    saveConfig(config = null, testMode = false) {
        try {
            const configToSave = config || this.config;
            if (!configToSave) {
                throw new Error('No configuration to save');
            }

            // Validate before saving with enhanced test mode support
            const validation = validateConfig(configToSave, {
                testMode,
                strict: false,
                allowExtraFields: true
            });
            if (!validation.success) {
                throw new Error(`Invalid configuration: ${validation.errors.join(', ')}`);
            }

            const configContent = JSON.stringify(configToSave, null, 2);
            fs.writeFileSync(this.configPath, configContent, 'utf8');

            this.config = configToSave;
            this.lastModified = new Date();

            console.log('Configuration saved successfully');
            return configToSave;
        } catch (error) {
            console.error('Failed to save configuration:', error.message);
            throw error;
        }
    }

    /**
     * Reload configuration from file
     */
    reloadConfig() {
        this.config = null;
        this.lastModified = null;
        return this.loadConfig();
    }

    /**
     * Get all providers
     * @returns {Object} Providers configuration
     */
    getProviders() {
        return this.get('providers', {});
    }

    /**
     * Get current provider model
     * @returns {string} Current provider model identifier
     */
    getCurrentProviderModel() {
        return this.get('current_provider_model', '');
    }

    /**
     * Set current provider model
     * @param {string} providerModel - Provider model identifier
     */
    setCurrentProviderModel(providerModel) {
        this.set('current_provider_model', providerModel);
    }

    /**
     * Get provider configuration
     * @param {string} providerName - Provider name
     * @returns {Object} Provider configuration
     */
    getProvider(providerName) {
        return this.get(`providers.${providerName}`, null);
    }

    /**
     * Update provider configuration
     * @param {string} providerName - Provider name
     * @param {Object} providerConfig - Provider configuration
     */
    updateProvider(providerName, providerConfig) {
        this.set(`providers.${providerName}`, providerConfig);
    }

    /**
     * Delete provider
     * @param {string} providerName - Provider name
     */
    deleteProvider(providerName) {
        const config = this.loadConfig();
        if (config.providers && config.providers[providerName]) {
            delete config.providers[providerName];
            this.saveConfig(config);
        }
    }

    /**
     * Add model to provider
     * @param {string} providerName - Provider name
     * @param {Object} model - Model configuration
     */
    addModel(providerName, model) {
        const provider = this.getProvider(providerName);
        if (provider) {
            if (!provider.models) {
                provider.models = [];
            }
            provider.models.push(model);
            this.updateProvider(providerName, provider);
        }
    }

    /**
     * Remove model from provider
     * @param {string} providerName - Provider name
     * @param {string} modelId - Model ID
     */
    removeModel(providerName, modelId) {
        const provider = this.getProvider(providerName);
        if (provider && provider.models) {
            provider.models = provider.models.filter(model => model.id !== modelId);
            this.updateProvider(providerName, provider);
        }
    }

    /**
     * Get logging configuration
     * @returns {Object} Logging configuration
     */
    getLoggingConfig() {
        return this.get('logging', {
            level: 'info',
            file_enabled: true,
            console_enabled: true
        });
    }

    /**
     * Get HTTP server configuration
     * @returns {Object} HTTP server configuration
     */
    getHttpServerConfig() {
        return this.get('http_server', {
            port: 3000,
            auto_start: false,
            host: 'localhost'
        });
    }

    /**
     * Get MCP configuration
     * @returns {Object} MCP configuration
     */
    getMcpConfig() {
        return this.get('mcp', {
            server_name: 'vision-analyzer',
            server_version: '1.2.13',
            timeout: 30000
        });
    }

    /**
     * Get feature flags
     * @returns {Object} Feature flags
     */
    getFeatures() {
        return this.get('features', {
            auto_model_selection: true,
            cache_analysis: false,
            debug_mode: false
        });
    }

    /**
     * Check if configuration file exists
     * @returns {boolean} True if configuration file exists
     */
    exists() {
        return fs.existsSync(this.configPath);
    }

    /**
     * Create default configuration file
     * @param {boolean} testMode - Whether to create test-friendly configuration
     */
    createDefaultConfig(testMode = false) {
        // 检查配置文件是否已存在，避免覆盖现有配置
        if (fs.existsSync(this.configPath)) {
            console.log(`[JsonConfigManager] 配置文件已存在: ${this.configPath}，跳过默认配置创建`);
            return this.loadConfig();
        }

        const defaultConfig = {
            version: "1.0.0",
            current_provider_model: "tencent-hunyuan-vision",
            providers: {
                zai: {
                    api_key: testMode ? "test_api_key" : "",
                    base: "https://open.bigmodel.cn/api/paas/v4",
                    models: [
                        {
                            id: "glm-4.5v",
                            name: "GLM-4.5 Vision",
                            type: "vision",
                            capabilities: ["image_analysis"],
                            max_tokens: 8192,
                            supports_vision: true,
                            enabled: true
                        }
                    ],
                    timeout: 30000,
                    max_retries: 3
                },
                moonshot: {
                    api_key: testMode ? "test_moonshot_key" : "",
                    base: "https://api.moonshot.cn/v1",
                    models: [
                        {
                            id: "moonshot-v1-8k-vision-preview",
                            name: "Moonshot Vision 8K",
                            type: "vision",
                            capabilities: ["image_analysis"],
                            max_tokens: 8192,
                            supports_vision: true,
                            enabled: true
                        }
                    ],
                    timeout: 30000,
                    max_retries: 3
                },
                tencent: {
                    api_key: testMode ? "test_tencent_key" : "",
                    base: "https://api.hunyuan.tencentcloudapi.com",
                    models: [
                        {
                            id: "hunyuan-vision",
                            name: "Hunyuan Vision",
                            type: "vision",
                            capabilities: ["image_analysis"],
                            max_tokens: 8192,
                            supports_vision: true,
                            enabled: true
                        }
                    ],
                    timeout: 30000,
                    max_retries: 3
                }
            },
            http_server: {
                port: 3000,
                auto_start: false,
                host: "localhost",
                cors: {
                    enabled: true,
                    origins: ["*"]
                }
            },
            logging: {
                level: "info",
                retention_days: 30,
                max_file_size: "10MB",
                file_enabled: true,
                console_enabled: true
            },
            mcp: {
                server_name: "vision-analyzer",
                server_version: "1.2.13",
                timeout: 30000
            },
            features: {
                auto_model_selection: true,
                cache_analysis: false,
                debug_mode: false
            },
            test: {
                enabled: testMode,
                log_level: testMode ? "info" : "error"
            }
        };

        if (testMode) {
            console.log(`[JsonConfigManager] 创建测试模式配置文件: ${this.configPath}`);
        } else {
            console.log(`[JsonConfigManager] 创建生产模式配置文件: ${this.configPath}`);
        }

        this.saveConfig(defaultConfig, testMode);
        return defaultConfig;
    }
}

module.exports = JsonConfigManager;